package com.ihr360.expr.engine;

import com.ihr360.expr.ExprError;
import com.ihr360.expr.ExprException;
import com.ihr360.expr.context.IEvaluationContext;
import com.ihr360.expr.core.Expr;
import com.ihr360.expr.core.ExprFunction;
import com.ihr360.expr.core.ExprVariable;
import com.ihr360.expr.function.ExcelFunctionProvider;
import com.ihr360.expr.function.FunctionManager;
import com.ihr360.expr.parser.ExprLexer;
import com.ihr360.expr.parser.ExprParser;
import com.ihr360.expr.parser.IParserVisitor;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class BasicEvaluationCallback implements IEvaluationContext, IParserVisitor {
    private FunctionManager functions = new FunctionManager();
    private Map<String, Expr> variables = new HashMap<>();

    public Expr parse(String expr) throws IOException, ExprException {
        ExprParser ep = new ExprParser();
        ep.setParserVisitor(this);
        ep.parse(new ExprLexer(expr));
        return ep.get();
    }
    public BasicEvaluationCallback() {
        functions.add(new ExcelFunctionProvider());
    }


    public void addVariable(String name, Expr value) {
        variables.put(name, value);
    }

    @Override
    public Expr evaluateFunction(ExprFunction function) throws ExprException {
        return functions.evaluate(this, function);
    }

    @Override
    public Expr evaluateVariable(ExprVariable variable) throws ExprException {
        String name = variable.getName().toUpperCase();
        if (variables.containsKey(name)) {
            return variables.get(name);
        }
        Expr e = variables.get(name);
        if (e == null)
            return ExprError.NAME;
        return e;
    }

    @Override
    public void annotateVariable(ExprVariable variable) throws ExprException {

    }

    @Override
    public void annotateFunction(ExprFunction function) throws ExprException {

    }
}